package e2e

import (
	"testing"

	"github.com/lab-online/internal/user/entity"
	"github.com/lab-online/internal/user/infra/model"
	"github.com/lab-online/pkg/auth"
	"github.com/lab-online/pkg/e2e"
	"github.com/lab-online/pkg/resp"
	"github.com/stretchr/testify/assert"
)

func (ctx *context) BeforeAll() {
}

type context struct {
	*e2e.Context
}

func (ctx *context) AfterAll() {
	// ctx.Database.Exec("DELETE FROM users")

}

func Describe(ctx *e2e.Context) (string, func(*testing.T)) {
	return e2e.NewDescribe("users", &context{ctx})
}

func (ctx *context) utilsCreateUser(username string, role auth.Role, pwd string) {
	hashedPwd, _ := entity.HashPassword(pwd)
	ctx.Database.Save(&model.User{
		Username: username,
		Role:     uint8(role),
		Password: hashedPwd})
}

func (ctx *context) utilsDeleteUser(username string) {
	ctx.Database.Delete(&model.User{}, "username = ?", username)
}

func (ctx *context) Case1() (string, func(*testing.T)) {
	ctx.utilsCreateUser("02240302", auth.RoleStudent, "12345678")
	return "登录成功并返回token", func(t *testing.T) {
		response := ctx.JSONRequest(&e2e.Request{
			Method: "POST",
			Path:   "/api/v1/users/login",
			Body: map[string]any{
				"username": "02240302",
				"password": "12345678",
			},
		})

		assert.Equal(t, 200, response.Code)

		body := e2e.JSONBodyParser[resp.SuccessRespBody[struct {
			AccessToken string `json:"accessToken"`
		}]](response)

		assert.Equal(t, 20101, body.Code)
		assert.NotEmpty(t, body.Data.AccessToken)
	}
}

func (ctx *context) Case2() (string, func(*testing.T)) {
	ctx.utilsCreateUser("03240331", auth.RoleAll, "12345678")
	adminBearerToken := ctx.GenBearerToken("03240331", auth.RoleAll)
	return "获取当前用户信息", func(t *testing.T) {
		response := ctx.JSONRequest(&e2e.Request{
			Method: "GET",
			Path:   "/api/v1/users/profile",
			Header: map[string]string{
				"Authorization": adminBearerToken,
			},
		})

		assert.Equal(t, 200, response.Code)

		body := e2e.JSONBodyParser[resp.SuccessRespBody[struct {
			Username string `json:"username"`
			Name     string `json:"name"`
			Role     uint8  `json:"role"`
		}]](response)

		assert.Equal(t, 20102, body.Code)
		assert.NotEmpty(t, body.Data)
	}
}

func (ctx *context) Case3() (string, func(*testing.T)) {
	ctx.utilsDeleteUser("01240331")
	adminBearerToken := ctx.GenBearerToken("01240331", auth.RoleAdmin)
	return "注册用户", func(t *testing.T) {
		response := ctx.JSONRequest(&e2e.Request{
			Method: "POST",
			Path:   "/api/v1/users",
			Body: map[string]any{
				"username": "01240331",
				"password": "12345678",
				"role":     1,
				"name":     "学生1",
			},
			Header: map[string]string{
				"Authorization": adminBearerToken,
			},
		})

		assert.Equal(t, 201, response.Code)

		body := e2e.JSONBodyParser[resp.SuccessRespBody[any]](response)

		assert.Equal(t, 20100, body.Code)
		assert.Empty(t, body.Data)
	}
}

func (ctx *context) Case5() (string, func(*testing.T)) {
	ctx.utilsCreateUser("01240302", auth.RoleStudent, "12345678")
	ctx.utilsDeleteUser("01240302")
	adminBearerToken := ctx.GenBearerToken("admin001", auth.RoleAdmin)
	return "注册被软删除的用户", func(t *testing.T) {
		response := ctx.JSONRequest(&e2e.Request{
			Method: "POST",
			Path:   "/api/v1/users",
			Body: map[string]any{
				"username": "01240302",
				"password": "12345678",
				"role":     1,
				"name":     "学生1",
			},
			Header: map[string]string{
				"Authorization": adminBearerToken,
			},
		})

		assert.Equal(t, 201, response.Code)

		body := e2e.JSONBodyParser[resp.SuccessRespBody[any]](response)

		assert.Equal(t, 20100, body.Code)
		assert.Empty(t, body.Data)
	}
}
